package com.zyf.system.config;

import com.zyf.system.controller.BaseController;
import com.zyf.system.entity.ParamError;
import com.zyf.system.until.Constant;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler extends BaseController {

    @ExceptionHandler(BindException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Map<String,Object> handleValidationException(BindException e){
        return createResponse(Constant.PARAM_ERROR, getErrorMessage(e.getBindingResult()),getError(e.getBindingResult()));
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Map<String,Object> handleValidationException(ConstraintViolationException e){
        List<ParamError> errorList = new ArrayList<>();
        for(ConstraintViolation<?> s:e.getConstraintViolations()){
            String path = s.getPropertyPath().toString();
            String[] key = path.split("\\.");
            String errorKey = key[key.length-1];
            ParamError paramError = new ParamError(errorKey,s.getMessage());
            errorList.add(paramError);
        }
        return createResponse(Constant.PARAM_ERROR, getErrorMessage(errorList),errorList);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Map<String,Object> handleValidationException(MethodArgumentNotValidException e){
        return createResponse(Constant.PARAM_ERROR, getErrorMessage(e.getBindingResult()),getError(e.getBindingResult()));
    }

    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> paramExceptionHandler(IllegalArgumentException e) {
        return createResponse(Constant.FAIL, e.getMessage(), null);
    }

//    @ExceptionHandler({AccessDeniedException.class})
//    @ResponseStatus(HttpStatus.OK)
//    public Map<String, Object> accessExceptionHandler(AccessDeniedException e) {
//        return createResponse("403", "无访问权限", e.getMessage());
//    }

    @ExceptionHandler({Exception.class})
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> paramExceptionHandler(Exception e) {
        return createResponse(Constant.FAIL, "系统异常:" + e.getMessage(), null);
    }

    protected List<ObjectError> getError(BindingResult bindingResult){
        return bindingResult.getAllErrors();
    }
}
